package util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import orm.Token;


import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.UUID;

/**
 * Created by langdon on 2017/7/9.
 */
public class JWTToken {

    private JWTToken() {
    }

    private static final UUID uuid = UUID.randomUUID();

    /**
     * 产生JWTtoken
     * @param userId 用户的id
     * @return 返回加密得到的JWTtoken
     */
    public static String encode(int userId) {
        //1.算出header，playload
        Token token= new Token();

        JSONObject header=new JSONObject();
        header.put("typ","JWT");
        header.put("alg","HS256");
        token.setHeader(header);

        JSONObject payload=new JSONObject();
        payload.put("iss","keyverify");
        //当前系统时间 + 2小时
        payload.put("exp",Long.toString(System.currentTimeMillis()+7200000));
        payload.put("id",Integer.toString(userId));
        token.setPayload(payload);


        //2.base64对header、payload进行加密
        byte [] encodedHeader = Base64.getEncoder().encode(header.toString().getBytes());
        byte [] encodedPayload= Base64.getEncoder().encode(payload.toString().getBytes(StandardCharsets.UTF_8));

        String encodedString = new String(encodedHeader,StandardCharsets.UTF_8)  + "."+ new String(encodedPayload,StandardCharsets.UTF_8);

        //3.生成signature
        String signature = HMACSHA256(encodedString.getBytes(StandardCharsets.UTF_8),
                uuid.toString().replace("-","").getBytes(StandardCharsets.UTF_8));

        String encodedToken =  encodedString + "." + signature;
        return  encodedToken;
    }


    private static String HMACSHA256(byte[] data, byte[] key)
    {
        try  {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(signingKey);
            return byte2hex(mac.doFinal(data));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String byte2hex(byte[] b)
    {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b!=null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                hs.append('0');
            hs.append(stmp);
        }
        return hs.toString().toUpperCase();
    }

    /**
     * 对用户token进行解密，得到 header、payload
     * @param token 鉴权用的JWTtoken
     * @return 解密后得到的token
     */
    public static Token decode(String token){
        String [] tokens= token.split("\\.");
        String header = tokens[0];
        String payload= tokens[1];
        String decodedHeader = new String (Base64.getUrlDecoder().decode(header.getBytes(StandardCharsets.UTF_8)) , StandardCharsets.UTF_8);
        String decodedPyload = new String (Base64.getUrlDecoder().decode(payload.getBytes(StandardCharsets.UTF_8)) , StandardCharsets.UTF_8);
        return new Token((JSONObject) JSON.parse(decodedHeader),(JSONObject) JSON.parse(decodedPyload));
    }
}